package cn.mesmile.order.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.mesmile.order.dto.Product;
import cn.mesmile.order.entity.Order;
import cn.mesmile.order.fallback.AccountServiceClient;
import cn.mesmile.order.fallback.ProductServiceClient;
import cn.mesmile.order.mapper.OrderMapper;
import cn.mesmile.order.service.OrderService;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * @author zb
 * @date 2020/12/16 11:11
 * @Description
 */
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS,readOnly = true,rollbackFor = Exception.class)
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final ProductServiceClient productServiceClient;

    private final AccountServiceClient accountServiceClient;

//    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean transaction(Long productId, Long number) {
        if (number <= 0){
            return false;
        }
        //  ①、检查库存
        Product product = productServiceClient.getProduct(1L);
        if (product == null){
            throw new RuntimeException("找不到商品");
        }
        long result = product.getStock() - number;
        if (result < 0) {
            throw new RuntimeException("库存不足");
        }

        // ②、创建订单
        Order order = new Order();
        order.setUserId(1000L);
        order.setOrderName(product.getName()+DateUtil.now());
        boolean save = save(order);
        if (!save) {
            throw new RuntimeException("创建订单失败");
        }

        // ③、减去库存
        Boolean update = productServiceClient.update(productId, result);
        if (!update) {
            throw new RuntimeException("减去库存失败");
        }

        BigDecimal multiply = product.getPrice().multiply(BigDecimal.valueOf(number));
        // ④、扣除余额
        Boolean deductBalance = accountServiceClient.deductBalance(order.getUserId(), multiply);
        if (!deductBalance) {
            throw new RuntimeException("扣除余额失败");
        }

        // ⑤、修改订单状态
        Long orderId = order.getId();
        if (orderId ==null ) {
            throw new RuntimeException("没有获取到订单号异常");
        }
        LambdaUpdateWrapper<Order> lambdaUpdate = Wrappers.lambdaUpdate();
        lambdaUpdate.set(Order::getState, 1);
        lambdaUpdate.eq(Order::getId,orderId);
        boolean updateOrder = update(lambdaUpdate);
        if (!updateOrder) {
            throw new RuntimeException("修改订单状态失败");
        }

        return true;
    }


}
